#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
// #include "parse.h"
// #include "response.h"
#include "client_pool.h"

#define ECHO_PORT 9999
#define BUF_SIZE 4096

int close_socket(int sock){
    if (close(sock)){
        fprintf(stderr, "Failed closing socket.\n");
        return 1;
    }
    return 0;
}

int main(int argc, char* argv[]){
    int sock, client_sock;
    // ssize_t readret;
    socklen_t cli_size;
    struct sockaddr_in addr, cli_addr;
    // char recv_buf[BUF_SIZE];
    client_pool pool;

    fprintf(stdout, "----- Echo Server -----\n");
    
    // 创建socket
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1){    
        fprintf(stderr, "Failed creating socket.\n");
        return EXIT_FAILURE;
    }

    addr.sin_family = AF_INET;          // IPv4
    addr.sin_port = htons(ECHO_PORT);   // port
    addr.sin_addr.s_addr = INADDR_ANY;  // ip = 0.0.0.0 (本机)

    // 绑定socket
    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr))){
        close_socket(sock);
        fprintf(stderr, "Failed binding socket.\n");
        return EXIT_FAILURE;
    }

    // 监听socket，允许连入5个客户端
    if (listen(sock, 5)){
        close_socket(sock);
        fprintf(stderr, "Error listening on socket.\n");
        return EXIT_FAILURE;
    }

    init_pool(sock, &pool);

    // 接收客户端的数据并回显
    while (1){
        pool.read_fds = pool.all_set;
        pool.ready_num = select(pool.max_fd+1, &pool.read_fds, NULL, NULL, NULL);

        if(pool.ready_num == 0){
            continue;
        }
        else if(pool.ready_num < 0){
            // dump_log("[Main] Select error");
            printf("[Main] Select error");
        }

        // 如果sock监听到新的连接则执行if语句内容 
        // 否则调用handle_clients处理已建立连接的客户端
        cli_size = sizeof(cli_addr);
        if(FD_ISSET(sock, &pool.read_fds)){
            // accept客户端 并打印客户端信息
            if((client_sock=accept(sock, (struct sockaddr *) &cli_addr, &cli_size)) == -1){
                // close(sock);
                fprintf(stderr, "Error accepting connection.\n");
                // return EXIT_FAILURE;
                continue;
            }
            getpeername(client_sock, (struct sockaddr *)&cli_addr, &cli_size); 
            printf("Accept new connection from %s:%d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
            add_client_to_pool(client_sock, &pool);

            if(pool.ready_num <= 0){
                continue;
            }
        }

        handle_clients(&pool);


        // 接收客户端的数据并回显 
        // 这里之后应该还要改，改成接收完所有数据再处理，不然可能会把数据部分当成了头部来处理
        // 目前只能处理短数据
        // readret = 0;
        // while((readret = recv(client_sock, recv_buf, BUF_SIZE, 0)) >= 1){ // 接收
        //     // handle_request(client_sock, readret, recv_buf);
        //     process_pipelined_request(client_sock, recv_buf);

        //     // if (send(client_sock, send_buf, readret, 0) != readret){      // 回显
        //     //     close_socket(client_sock);
        //     //     close_socket(sock);
        //     //     fprintf(stderr, "Error sending to client.\n");
        //     //     return EXIT_FAILURE;
        //     // }
        //     memset(recv_buf, 0, BUF_SIZE);
        // } 

        // if (readret == -1){
        //     close_socket(client_sock);
        //     close_socket(sock);
        //     fprintf(stderr, "Error reading from client socket.\n");
        //     return EXIT_FAILURE;
        // }

        // if (close_socket(client_sock)){
        //     close_socket(sock);
        //     fprintf(stderr, "Error closing client socket.\n");
        //     return EXIT_FAILURE;
        // }
    }

    close_socket(sock);
    return EXIT_SUCCESS;
}